var createError = require('http-errors')
var express = require('express')
var path = require('path')
var cookieParser = require('cookie-parser')
var logger = require('morgan')
// 定义验证规则
const joi = require('joi')
// 导入 cors 中间件
const cors = require('cors')

const app = express()

// view engine setup
// app.set('views', path.join(__dirname, 'views'))
// app.set('view engine', 'jade')

// app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))
// 将 cors 注册为全局中间件
app.use(cors())

// 在处理函数中，需要多次调用 `res.send()` 向客户端响应 `处理失败` 的结果，为了简化代码，可以手动封装一个 res.cc() 函数
//
// 响应数据的中间件
app.use(function (req, res, next) {
  // code = 200 为成功； code = 400 为失败； 默认将 code 的值设置为 400，方便处理失败的情况
  res.cc = function (err, code = 400) {
    res.send({
      // 状态
      code,
      // 状态描述，判断 err 是 错误对象 还是 字符串
      message: err instanceof Error ? err.message : err,
    })
  }
  next()
})

// 解析 token 的中间件
const expressJWT = require('express-jwt')
const config = require('./config')
// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(
  expressJWT({ secret: config.jwtSecretKey, algorithms: ['HS256'] }).unless({
    path: [/^\/api\//],
  })
)

// 导入并使用用户信息路由模块
const indexRouter = require('./routes/index')
const userRouter = require('./routes/user.js')
const userinfoRouter = require('./routes/userinfo.js')
const orderRouter = require('./routes/order.js')
const carRouter = require('./routes/car.js')
const logisticsRouter = require('./routes/logistics.js')
const noticeRouter = require('./routes/notice.js')
app.use('/', indexRouter)
app.use('/api', userRouter)
// 注意：以 /my 开头的接口，都是有权限的接口，需要进行 Token 身份认证
app.use('/my', userinfoRouter)
app.use('/order', orderRouter)
app.use('/car', carRouter)
app.use('/logistics', logisticsRouter)
app.use('/notice', noticeRouter)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404))
})

//定义错误级别的中间件
app.use((err, req, res, next) => {
  //验证失败导致的错误
  if (err instanceof joi.ValidationError) return res.cc(err + '222')
  //身份认证失败后的错误
  if (err.name === 'UnauthorizedError') return res.cc('身份认证失败1')
  // 未知的错误
  res.cc(err + '未知的错误', 500)
})

// 调用 app.listen 方法，指定端口号并启动web服务器
app.listen(3000, function () {
  console.log('api server running at http://127.0.0.1:3000')
})
